<template>
  <div class="app-container">
    <SideBar>
      <div slot="left" class="left-content">
        <el-input
          placeholder="请输入内容"
          v-model="searchKey"
          class="input-with-select"
          size="small"
          @keyup.enter.native="handleFilter"
        >
          <i
            slot="suffix"
            class="el-input__icon el-icon-search"
            @click="handleFilter"
          ></i>
        </el-input>
        <div class="tree-container" v-loading="treeLoading">
          <el-tree
            ref="tree"
            node-key="id"
            :data="treeData"
            :props="defaultProps"
            :filter-node-method="handleFilterNode"
            :default-expanded-keys="defaultExpandedKeys"
            @node-click="handleNodeClick"
            @node-contextmenu="handleContextmenu"
          >
            <span
              slot-scope="{ node, data }"
              :class="{'custom-tree-node':true, 'active-node':activeNode&&activeNode.id===data.id }"
            >
              <span v-if="data.nodeType===node_type.GROUP">
                <svg-icon
                  v-show="node.expanded"
                  icon-class="folder-open"
                  class-name="folder-icon"
                />
                <svg-icon
                  v-show="!node.expanded"
                  icon-class="folder"
                  class-name="folder-icon"
                />
              </span>
              <span class="el-tree-node__label">{{ node.label }}</span>
            </span>
          </el-tree>
        </div>
        <ul
          v-show="contextVisible"
          :style="{left:contextPosition.left+'px',top:contextPosition.top+'px',transform:contextPosition.transform}"
          class="contextmenu"
        >
          <li
            v-for="c in contextList"
            :key="c.id"
            @click="handleContextClick(c.name)"
          >{{c.label}}</li>
        </ul>
      </div>
      <Group
        v-show="activeNode.nodeType===node_type.GROUP"
        :data="groupData"
        @save-success="handleSavedGroup"
      />
      <Temp
        v-show="activeNode.nodeType===node_type.TEMPLATE"
        v-loading="getTemplateLoading"
        :data="templateData"
        @save-success="handleSaveTemplate"
      />
    </SideBar>
  </div>
</template>

<script>
import Temp from './temp.vue'
import Group from './group.vue'
import { NODE_TYPE } from '../enum'
import SideBar from '@/components/SideBar'
import { getExpandedNodeKeys } from '@/utils/tree'
import {
  getImportingTree,
  getTemplateInfo,
  deleteGroup,
  deleteTemplate
} from '@/api/import/template'

const ContextConfig = {
  root: ['addGroup'],
  group: ['addGroup', 'addTemp', 'delGroup'],
  temp: ['delTemp']
}
const ContextListData = [
  { id: 1, label: '新增分组', name: 'addGroup' },
  { id: 2, label: '新增子节点', name: 'addTemp' },
  { id: 3, label: '删除分组', name: 'delGroup' },
  { id: 4, label: '删除', name: 'delTemp' }
]
export default {
  name: 'Template',
  components: { Temp, Group, SideBar },
  data() {
    return {
      searchKey: '',
      activeNode: {},
      treeData: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      // 树默认展开节点
      defaultExpandedKeys: [],
      contextVisible: false,
      contextPosition: {
        left: 0,
        top: 0,
        transform: 'unset'
      },
      contextList: [],
      contextNode: {},
      groupData: {},
      templateData: {},
      treeLoading: false,
      getTemplateLoading: false
    }
  },
  computed: {
    node_type() {
      return NODE_TYPE
    }
  },
  created() {
    this.getTreeData()
  },
  methods: {
    getTreeData() {
      this.treeLoading = true
      getImportingTree().then((res) => {
        // 设置默认展开（包括新增删除等操作后）
        const defaultVal = res.data?.length ? [res.data[0].id] : []
        this.defaultExpandedKeys = getExpandedNodeKeys(this.$refs.tree?.store.nodesMap,'id',defaultVal,true)
        this.treeData = res.data || []
        this.treeLoading = false
      }).catch(()=>{
        this.treeLoading = false
      })
    },
    handleFilter() {
      this.$refs.tree.filter(this.searchKey)
    },
    handleFilterNode(value, data, node) {
      return data.name.includes(value)
    },
    handleNodeClick(data) {
      if (!data.id) {
        this.templateData = { tree: { ...data }}
        this.groupData = { ...data }
        return
      }
      if (this.activeNode.id === data.id) {
        return
      }
      this.activeNode = data
      if (data.nodeType === NODE_TYPE.TEMPLATE) {
        this.getTemplateLoading = true
        getTemplateInfo(data.id).then((res) => {
          this.templateData = res.data
          this.getTemplateLoading = false
        }).catch(() => {
          this.getTemplateLoading = false
        })
      } else {
        this.groupData = { ...data }
      }
    },
    handleContextmenu(event, data, node) {
      if (['0', 0].includes(data.parentId)) {
        this.contextList = ContextListData.filter((ele) =>
          ContextConfig.root.includes(ele.name)
        )
      } else if (data.nodeType === NODE_TYPE.TEMPLATE) {
        this.contextList = ContextListData.filter((ele) =>
          ContextConfig.temp.includes(ele.name)
        )
      } else {
        this.contextList = ContextListData.filter((ele) =>
          ContextConfig.group.includes(ele.name)
        )
      }
      this.contextPosition.left = event.clientX
      this.contextPosition.top = event.clientY
      const appmain = document.getElementById('app-main')
      if (event.clientY + 10 + 30 * this.contextList.length >= appmain.offsetHeight) {
        this.contextPosition.transform = 'translateY(calc(-100% - 5px))'
      } else {
        this.contextPosition.transform = 'unset'
      }
      this.contextNode = data
      this.openContext()
    },
    openContext() {
      this.contextVisible = true
    },
    closeContext() {
      this.contextVisible = false
    },
    handleContextClick(name) {
      switch (name) {
        case 'addGroup':
          this.activeNode = {
            nodeType: NODE_TYPE.GROUP,
            parentId: this.contextNode.id
          }
          this.handleNodeClick(this.activeNode)
          break
        case 'addTemp':
          this.activeNode = {
            nodeType: NODE_TYPE.TEMPLATE,
            parentId: this.contextNode.id
          }
          this.handleNodeClick(this.activeNode)
          break
        case 'delGroup':
          if (this.contextNode.id) {
            this.$confirm('是否确认删除该分组？', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
              .then(() => {
                deleteGroup(this.contextNode.id).then((res) => {
                  this.getTreeData()
                  this.$message({
                    type: 'success',
                    message: '删除成功！'
                  })
                })
              })
              .catch(() => {})
          }
          break
        case 'delTemp':
          if (this.contextNode.id) {
            this.$confirm('是否确认删除该模板？', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
              .then(() => {
                deleteTemplate(this.contextNode.id).then((res) => {
                  this.getTreeData()
                  this.$message({
                    type: 'success',
                    message: '删除成功！'
                  })
                })
              })
              .catch(() => {})
          }
          break
      }
    },
    handleSavedGroup() {
      this.getTreeData()
      this.activeNode = {}
      this.templateData = {}
    },
    handleSaveTemplate() {
      this.getTreeData()
      this.activeNode = {}
      this.templateData = {}
    }
  },
  watch: {
    contextVisible(value) {
      if (value) {
        document.body.addEventListener('click', this.closeContext)
      } else {
        document.body.removeEventListener('click', this.closeContext)
      }
    }
  }
}
</script>

<style scoped lang="scss">
@import "../../../assets/styles/element-variables";
.app-container {
  .left-content {
    width: 100%;
    height: 100%;
  }
  .tree-container {
    margin-top: 10px;
    height: calc(100% - 32px - 10px);
    // overflow: auto;
  }
  .el-tabs {
    height: 100%;
    ::v-deep .el-tabs__content {
      height: calc(100% - 55px);
      overflow: hidden;
    }
  }
  .folder-icon {
    margin-right: 5px;
    color: $--color-primary;
  }
  .active-node {
    color: $--color-primary;
  }
}
</style>